# -*- coding: UTF-8 -*-
import re

def wrap(text, width):
    """
    Une fonction qui ajoute automatiquement des sauts de ligne au texte spécifié,
    tout en préservant les sauts de ligne et autres espaces déjà présents. Cette
    fonction suppose que les sauts de ligne existants sont des sauts de ligne
    POSIX (\n).
    Voir http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/148061
    """
    return reduce(lambda line, word, width=width: '%s%s%s' %
                  (line,
                   ' \n'[(len(line[line.rfind('\n')+1:])
                         + len(word.split('\n',1)[0]
                              ) >= width)],
                   word),
                  text.split(' ')
                 )

def truncate_words(s, num):
    "Tronque une chaîne après un certain nombre de mots."
    length = int(num)
    words = s.split()
    if len(words) > length:
        words = words[:length]
        if not words[-1].endswith('...'):
            words.append('...')
    return ' '.join(words)

def get_valid_filename(s):
    """
    Renvoie la chaîne spécifiée de telle sorte qu'elle puisse servir en tant
    que nom de fichier. Plus précisément, cette fonction élimine les espaces
    se trouvant au début et à la fin de la chaîne spécifiée; les autres espaces
    de la chaîne sont convertis en tirets bas; tous les caractères qu'il vaut
    mieux ne pas voir apparaître au sein d'un nom de fichier sont supprimés.
    >>> get_valid_filename("l'oreille de mélanie en 2004.jpg")
    'loreille_de_mlanie_en_2004.jpg'
    """
    s = s.strip().replace(' ', '_')
    return re.sub(r'[^-A-Za-z0-9_.]', '', s)

def fix_microsoft_characters(s):
    """
    Convertit les caractères propriétaires Microsoft (guillemets intelligents et
    autres tirets longs) en caractères propres.
    """
    # Sources :
    # http://stsdas.stsci.edu/bps/pythontalk8.html
    # http://www.waider.ie/hacks/workshop/perl/rss-fetch.pl
    # http://www.fourmilab.ch/webtools/demoroniser/
    return s
    s = s.replace('\x91', "'")
    s = s.replace('\x92', "'")
    s = s.replace('\x93', '"')
    s = s.replace('\x94', '"')
    s = s.replace('\xd2', '"')
    s = s.replace('\xd3', '"')
    s = s.replace('\xd5', "'")
    s = s.replace('\xad', '--')
    s = s.replace('\xd0', '--')
    s = s.replace('\xd1', '--')
    s = s.replace('\xe2\x80\x98', "'") # guillemet simple bizarre (ouvrant)
    s = s.replace('\xe2\x80\x99', "'") # guillemet simple bizarre (fermant)
    s = s.replace('\xe2\x80\x9c', '"') # guillemet double bizarre (ouvrant)
    s = s.replace('\xe2\x80\x9d', '"') # guillemet double bizarre (fermant)
    s = s.replace('\xe2\x81\x84', '/')
    s = s.replace('\xe2\x80\xa6', '...')
    s = s.replace('\xe2\x80\x94', '--')
    return s

def get_text_list(list_, last_word='ou'):
    """
    >>> get_text_list(['a', 'b', 'c', 'd'])
    'a, b, c ou d'
    >>> get_text_list(['a', 'b', 'c'], 'et')
    'a, b et c'
    >>> get_text_list(['a', 'b'], 'et')
    'a et b'
    >>> get_text_list(['a'])
    'a'
    >>> get_text_list([])
    ''
    """
    if len(list_) == 0: return ''
    if len(list_) == 1: return list_[0]
    return '%s %s %s' % (', '.join([i for i in list_][:-1]), last_word, list_[-1])

def normalize_newlines(text):
    return re.sub(r'\r\n|\r|\n', '\n', text)

def recapitalize(text):
    "Remet en majuscule un texte, en plaçant des majuscules après les symboles de ponctuation indiquant la fin d'une phrase."
    capwords = 'I Jayhawk Jayhawks Lawrence Kansas KS'.split()
    text = text.lower()
    capsRE = re.compile(r'(?:^|(?<=[\.\?\!] ))([a-z])')
    text = capsRE.sub(lambda x: x.group(1).upper(), text)
    for capword in capwords:
        capwordRE = re.compile(r'\b%s\b' % capword, re.I)
        text = capwordRE.sub(capword, text)
    return text

def phone2numeric(phone):
    "Convertit un numéro de téléphone contenant des lettres en son équivalent numérique."
    letters = re.compile(r'[A-PR-Y]', re.I)
    char2number = lambda m: {'a': '2', 'c': '2', 'b': '2', 'e': '3',
         'd': '3', 'g': '4', 'f': '3', 'i': '4', 'h': '4', 'k': '5',
         'j': '5', 'm': '6', 'l': '5', 'o': '6', 'n': '6', 'p': '7',
         's': '7', 'r': '7', 'u': '8', 't': '8', 'w': '9', 'v': '8',
         'y': '9', 'x': '9'}.get(m.group(0).lower())
    return letters.sub(char2number, phone)

# Ce code provient de http://www.xhaus.com/alan/python/httpcomp.html#gzip
# Nous avons la permission de l'utiliser.
def compress_string(s):
    import cStringIO, gzip
    zbuf = cStringIO.StringIO()
    zfile = gzip.GzipFile(mode='wb', compresslevel=6, fileobj=zbuf)
    zfile.write(s)
    zfile.close()
    return zbuf.getvalue()